home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 2010 April / PCWorld0410.iso / pluginy Firefox / 5817 / 5817.xpi / chrome / content / exim.js < prev    next >
Text File  |  2010-02-11  |  25KB  |  691 lines

  1. Components.utils.import("resource://sqlitemanager/fileIO.js");
  2. Components.utils.import("resource://sqlitemanager/tokenize.js");
  3.  
  4. var Database;
  5. var SmExim = {
  6.   importWorker: null, //for worker thread
  7.  
  8.   sExpType: "",
  9.   sObjectName: null,
  10.   sObjectType: null,
  11.   msDbName: "main",
  12.  
  13.   mFileToImport: null,
  14.   msLeafName: null,
  15.  
  16.   mPrevTabId: null,
  17.  
  18.   init: function() {
  19.     this.msDbName = null;
  20.     this.sObjectType = null;
  21.     this.sObjectName = null;
  22.     this.mFileToImport = null;
  23.     this.msLeafName = null;
  24.   },
  25.  
  26.   loadCharsetMenu: function() {
  27.     var listbox = $$("eximFileCharSet");
  28.     listbox.removeAllItems();
  29.     var aSet = ['UTF-8', 'UTF-16', 'ISO-8859-1', 'GB2312', 'Windows-1251'];
  30.     for(var i in aSet)
  31.       listbox.appendItem(aSet[i], "");
  32.     listbox.selectedIndex = 0;
  33.   },
  34.  
  35.   loadDialog: function(sOpType, sObjectType, sObjectName) {
  36.     this.init();
  37.     this.msDbName = Database.logicalDbName;
  38.  
  39.     if (sOpType == "import") {
  40.       $$("tab-exim").label = sm_getLStr("eximTab.import.label");
  41.  
  42.       smShow(["exim-imp-ok", "eximFileSelection", "eximCsvTableNameLbl", "eximCsvTableName", "eximCsv_ignoreTrailingDelimiter"]);
  43.  
  44.       smHide(["exim-exp-ok", "eximSql-create-statement", "eximObjectSelection", "eximCsv-expSaveSetting"]);
  45.  
  46.       $$("eximFilename").value = "";
  47.       this.loadCharsetMenu();
  48.       return;
  49.     }
  50.     if (sOpType == "export") {
  51.       this.sObjectType = sObjectType;
  52.       this.sObjectName = sObjectName;
  53.       $$("tab-exim").label = sm_getLStr("eximTab.export.label");
  54. //      $$("eximSubtitle").value = sm_getLFStr("eximTab.export.subtitle", [sObjectType], 1) + this.sObjectName;
  55.       smHide(["exim-imp-ok", "eximFileSelection", "eximCsvTableNameLbl", "eximCsvTableName", "eximCsv_ignoreTrailingDelimiter"]);
  56.  
  57.       smShow(["exim-exp-ok", "eximSql-create-statement", "eximObjectSelection", "eximCsv-expSaveSetting"]);
  58.  
  59.       this.loadDbNames("eximDbName", Database.logicalDbName);
  60.       this.loadObjectNames("eximObjectNames", this.sObjectName, sObjectType);
  61.   
  62.       $$("eximLblObjectType").value = sm_getLStr("eximLblObjectType") + sObjectType;
  63.       return;
  64.     }
  65.  
  66.   },
  67.   
  68.   loadObjectNames: function(sListBoxId, sTableName, sObjectType) {
  69.     var dbName = $$("eximDbName").value;
  70.     var listbox = $$(sListBoxId);
  71.  
  72.     var aObjectNames = [];
  73.     if (sObjectType == "table") {
  74.       var aMastTableNames = Database.getObjectList("master", dbName);
  75.        var aNormTableNames = Database.getObjectList("table", dbName);
  76.       aObjectNames = aMastTableNames.concat(aNormTableNames);
  77.     }
  78.     else
  79.        aObjectNames = Database.getObjectList(sObjectType, dbName);
  80.     
  81.     PopulateDropDownItems(aObjectNames, listbox, sTableName);
  82.     this.onSelectObject();
  83.   },
  84.  
  85.   loadDbNames: function(sListBoxId, sDbName) {
  86.     var listbox = $$(sListBoxId);
  87.     var aObjectNames = Database.getDatabaseList();
  88.     PopulateDropDownItems(aObjectNames, listbox, sDbName);
  89.   },
  90.  
  91.   onSelectDb: function(sID) {
  92.     this.loadObjectNames("eximObjectNames", this.sObjectName, this.sObjectType);
  93.   },
  94.  
  95.   onSelectObject: function() {
  96.     this.sObjectName = $$("eximObjectNames").value;
  97.  
  98.     $$("eximSql-create-statement").hidden = false;
  99.     if (this.sObjectName == "sqlite_master" || this.sObjectName == "sqlite_temp_master") {
  100.       $$("eximSql-create-statement").checked = false;
  101.       $$("eximSql-create-statement").hidden = true;
  102.     }
  103.   },
  104.  
  105.   onSelectTab: function() {
  106.     switch($$("eximTabsFormat").selectedItem.getAttribute("id")) {
  107.       case "eximTabCsv":
  108.         this.sExpType = "csv";
  109.         break;
  110.       case "eximTabSql":
  111.         this.sExpType = "sql";
  112.         break;
  113.       case "eximTabXml":
  114.         this.sExpType = "xml";
  115.         break;
  116.     }
  117.   },
  118.  
  119.   doOKExport: function() {
  120.     this.onSelectTab();
  121.     var sTableName = $$("eximObjectNames").value;
  122.     var sDbName = $$("eximDbName").value;
  123.  
  124.     // get export file
  125.     const nsIFilePicker = Ci.nsIFilePicker;
  126.     var fp = Cc["@mozilla.org/filepicker;1"].createInstance(nsIFilePicker);
  127.     fp.init(window, sm_getLStr("exim.exportToFile"), nsIFilePicker.modeSave);
  128.     fp.appendFilters(nsIFilePicker.filterAll);
  129.     fp.defaultString = sTableName + "." + this.sExpType;
  130.     
  131.     var rv = fp.show();
  132.     
  133.     //if chosen then
  134.     if (rv != nsIFilePicker.returnOK && rv != nsIFilePicker.returnReplace) {
  135.       alert(sm_getLStr("exim.chooseFileExport"));
  136.       return false;
  137.     }
  138.     var file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsILocalFile);
  139.     file.initWithFile(fp.file);
  140.  
  141.     var foStream = Cc["@mozilla.org/network/file-output-stream;1"].createInstance(Ci.nsIFileOutputStream);
  142.     // use 0x02 | 0x10 to open file for appending.
  143.     foStream.init(file, 0x02 | 0x08 | 0x20, 0664, 0); // write, create, truncate
  144.  
  145.     var os = Cc["@mozilla.org/intl/converter-output-stream;1"].createInstance(Ci.nsIConverterOutputStream);
  146.     
  147.     // This assumes that fos is the nsIOutputStream you want to write to
  148.     os.init(foStream, "UTF-8", 0, 0x0000);
  149.     
  150.     var sQuery = "SELECT * FROM " + Database.getPrefixedName(sTableName, sDbName);
  151.     var iExportNum = 0;
  152.     switch(this.sExpType) {
  153.       case "csv":
  154.        //separator
  155.         var cSeparator = $$("eximCsv_separator").value;
  156.         if(cSeparator == "other")
  157.           cSeparator = $$("eximCsv_separator-text").value;
  158.         else if(cSeparator == "\\t")
  159.           cSeparator = "\t";
  160.         //encloser
  161.         var cEncloser = $$("eximCsv_encloser").value;
  162.         if(cEncloser == "other")
  163.          cEncloser = $$("eximCsv_encloser-text").value;
  164.         //colnames needed or not
  165.         var bColNames = $$("eximCsv_column-names").checked;
  166.  
  167.         iExportNum = this.writeCsvContent(os, sQuery, cSeparator, cEncloser, bColNames);
  168.         break;
  169.       case "sql":
  170.         var sDbName = $$("eximDbName").value;
  171.         var bTransact = $$("eximSql-transact-statement").checked;
  172.         var bCreate = $$("eximSql-create-statement").checked;
  173.         iExportNum = this.writeSqlContent(os, sDbName, this.sObjectName, bCreate, bTransact);
  174.         break;
  175.       case "xml":
  176.          var bType = $$("eximXml_type-attribute").checked;
  177.         iExportNum = this.writeXmlContent(os, sQuery, bType);
  178.         break;
  179.     }
  180.     os.close();
  181.     foStream.close();
  182.  
  183.     var sMessage = sm_getLFStr("exim.exportNum", [iExportNum, fp.file.path], 2);
  184.     var sType = "info";
  185.     sm_notify("boxNotifyExim", sMessage, sType);
  186.  
  187.     return false;
  188.   },
  189.  
  190.   writeCsvContent: function(foStream, sQuery, cSeparator, cEncloser, bColNames) {
  191.     Database.selectQuery(sQuery, true);
  192.     var allRecords = Database.getRecords();
  193.     var columns = Database.getColumns();
  194.     
  195.     if(bColNames) {
  196.       var data = [];
  197.       var i = 0;
  198.       for(var i in columns) {
  199.         if (cEncloser == "din" || cEncloser == '"') {
  200.           columns[i][0] = columns[i][0].replace("\"", "\"\"", "g");        
  201.           data.push('"' + columns[i][0] + '"');
  202.         }
  203.         else
  204.           data.push(cEncloser + columns[i][0] + cEncloser);
  205.         i++;
  206.       }
  207.       data = data.join(cSeparator) + "\n";
  208.       foStream.writeString(data);
  209.     }
  210.  
  211.     for(var i = 0; i < allRecords.length; i++) {
  212.       var row = allRecords[i];
  213.       var data = [];
  214.       for (var iCol = 0; iCol < row.length; iCol++) {
  215.         if (row[iCol] == null) {
  216.           data.push('');
  217.           continue;
  218.         }
  219.         if (cEncloser == "din") {
  220.           if (typeof row[iCol] == "string") {
  221.             row[iCol] = row[iCol].replace("\"", "\"\"", "g");        
  222.             row[iCol] = '"' + row[iCol] + '"';
  223.           }
  224.            data.push(row[iCol]);
  225.            continue;
  226.         }
  227.         if (cEncloser == '"') {
  228.           if (typeof row[iCol] == "string") {
  229.             row[iCol] = row[iCol].replace("\"", "\"\"", "g");        
  230.           }
  231.           row[iCol] = '"' + row[iCol] + '"';
  232.            data.push(row[iCol]);
  233.            continue;
  234.         }
  235.  
  236.         row[iCol] = cEncloser + row[iCol] + cEncloser;
  237.         data.push(row[iCol]);
  238.       }
  239.       data = data.join(cSeparator) + "\n";
  240.       foStream.writeString(data);
  241.     }
  242.     return allRecords.length;
  243.   },
  244.   //function depends on args and Database object only
  245.   writeSqlContent: function(foStream, sDbName, sTable, bCreate, bTransact) {
  246.     var data = "";
  247.  
  248.     if (bTransact) {
  249.       data = "BEGIN TRANSACTION;\n";
  250.       foStream.writeString(data);
  251.     }
  252.  
  253.     if (bCreate) {
  254.       var sTableSql = Database.getMasterInfo(sTable, sDbName).sql;
  255.       data = "DROP TABLE IF EXISTS " + SQLiteFn.quoteIdentifier(sTable) + ";\n";
  256.       data += sTableSql + ";\n";
  257.         foStream.writeString(data);
  258.  
  259.     }
  260.  
  261.     var sQuery = "SELECT * FROM " + Database.getPrefixedName(sTable, sDbName);
  262.     Database.selectQuery(sQuery, true);
  263.     var allRecords = Database.getRecords();
  264.     var columns = Database.getColumns();
  265.     var types = Database.getRecordTypes();
  266.     if (allRecords.length > 0) { 
  267.       var sInsert = "INSERT INTO " + SQLiteFn.quoteIdentifier(sTable) + " VALUES(";
  268.       for(var i = 0; i < allRecords.length; i++) {
  269.         data = sInsert;
  270.         var row = allRecords[i];
  271.         for (var iCol = 0; iCol < row.length; iCol++) {
  272.           if (iCol > 0) data += ",";
  273.           switch (types[i][iCol]) {
  274.             case 0:  data += SQLiteFn.getStrForNull(); break;
  275.             case 3:  data += SQLiteFn.quote(row[iCol]); break;
  276.             case 4:  data += row[iCol].toString(); break;
  277.             default: data += row[iCol]; break;
  278.           }
  279.         }
  280.         data += ");\n"
  281.         foStream.writeString(data);
  282.       }
  283.     }
  284.     if (bTransact) {
  285.       data = "COMMIT;\n";
  286.       foStream.writeString(data);
  287.     }
  288.     return allRecords.length;
  289.   },
  290.  
  291.   writeXmlContent: function(foStream, sQuery, bType) {
  292.     Database.selectQuery(sQuery, true);
  293.     var allRecords = Database.getRecords();
  294.     var columns = Database.getColumns();
  295.     var types = Database.getRecordTypes();
  296.     var sDbName = Database.getFileName();
  297.     var data = '<?xml version="1.0" encoding="utf-8" ?>\n';
  298.     data += "<!--\n";
  299.     data += "  GUID:  sqlite-manager@sqlite-manager.googlecode.com\n";
  300.     data += "  Homepage:  http://sqlite-manager.googlecode.com\n\n";
  301.     var d = new Date();
  302.     data += "  Generation Time: " + d.toGMTString() + "\n";
  303.     data += "  SQLite version: " + Database.sqliteVersion + "\n";
  304.     data += "-->\n\n";
  305.     data += "<!-- Database: " + sDbName + " -->\n";
  306.     foStream.writeString(data);
  307.  
  308.     var xmlDatabase = <{sDbName}/>;
  309.     var xmlColumn, data, xmlTable, colName;
  310.     for(var i = 0; i < allRecords.length; i++) {
  311.       var row = allRecords[i];
  312.       xmlTable = <{this.sObjectName}/>;
  313.       for (var iCol = 0; iCol < row.length; iCol++) {
  314.         colName = columns[iCol][0];
  315.         xmlColumn = <{colName}>{row[iCol]}</{colName}>;
  316.         if (bType)
  317.           xmlColumn.@type = types[i][iCol];
  318.         xmlTable.appendChild(xmlColumn);
  319.       }
  320.       xmlDatabase.appendChild(xmlTable);
  321.     }
  322.     data = xmlDatabase.toXMLString();
  323.     foStream.writeString(data);
  324.     return allRecords.length;
  325.   },
  326.  
  327.   selectFile: function() {
  328.     this.onSelectTab();
  329.     const nsIFilePicker = Ci.nsIFilePicker;
  330.     var fp = Cc["@mozilla.org/filepicker;1"].createInstance(nsIFilePicker);
  331.     fp.init(window, sm_getLStr("exim.chooseFileImport"), nsIFilePicker.modeOpen);
  332.     var fileFilters = {
  333.       csv: ["CSV Files", "*.csv"],
  334.       xml: ["XML Files", "*.xml"],
  335.       sql: ["SQL Files", "*.sql"]
  336.       };
  337.     var filter = fileFilters[this.sExpType];
  338.     fp.appendFilter(filter[0], filter[1]);
  339.     fp.appendFilters(nsIFilePicker.filterAll);
  340.     
  341.     var rv = fp.show();
  342.     if (rv != nsIFilePicker.returnOK && rv != nsIFilePicker.returnReplace) {
  343.       return false;
  344.     }
  345.  
  346.     //if chosen then
  347.     var file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsILocalFile);
  348.     file.initWithFile(fp.file);
  349.     //to support ADS
  350.     //file.initWithPath(fp.file.path + ":hhh.txt"); //ADS works
  351.     
  352.     this.msLeafName = fp.file.leafName;
  353.     $$("eximFilename").value = this.msLeafName;
  354.     this.mFileToImport = file;
  355.     var iLength = this.msLeafName.indexOf(".");
  356.     if (iLength >= 0)
  357.       this.msLeafName = this.msLeafName.substring(0, iLength);
  358.     $$("eximCsvTableName").value = this.msLeafName;
  359.     return true;
  360.   },
  361.  
  362.   doOKImport: function() {
  363.     if (this.mFileToImport == null) {
  364.       var sMessage = sm_getLStr("exim.alertNull.msg");
  365.       var sType = "critical";
  366.       sm_notify("boxNotifyExim", sMessage, sType);
  367.       return false;
  368.     }
  369.  
  370.     var file = this.mFileToImport;
  371.     var charset = $$("eximFileCharSet").value;
  372.  
  373.     var iImportNum = 0;
  374.     switch(this.sExpType) {
  375.       case "csv":
  376.         $$("eximStatus").hidden = false;
  377.         this.readCsvContent();
  378.         return;
  379.         break;
  380.       case "sql":
  381.         iImportNum = this.readSqlContent(file, charset);
  382.         break;
  383.       case "xml":
  384.         iImportNum = this.readXmlContent(file, charset);
  385.         break;
  386.     }
  387.     this.reportImportResult(iImportNum);
  388.   },
  389.  
  390.   handleImportCompletion: function(iStatus) {
  391.     this.importWorker.terminate();
  392.     $$("eximStatus").hidden = true;
  393.     this.reportImportResult(iStatus);
  394.   },
  395.  
  396.   showImportStatus: function(str) {
  397.     $$("eximStatusLabel").value = str;
  398.   },
  399.  
  400.   reportImportResult: function(iImportNum) {
  401.     if (iImportNum > 0) {
  402.       var sMessage = sm_getLStr("exim.importNum.title");
  403.       if (this.sExpType == "sql")
  404.         sMessage += " " + sm_getLFStr("exim.importNum.statements", [iImportNum], 1);
  405.       else
  406.         sMessage += " " + sm_getLFStr("exim.importNum.records", [iImportNum], 1);
  407.       var sType = "info";
  408.       sm_notify("boxNotifyExim", sMessage, sType);
  409.  
  410.       SQLiteManager.refreshDbStructure();
  411.       SQLiteManager.loadTabBrowse();
  412.     }
  413.     else if (iImportNum == 0) {
  414.       var sMessage = sm_getLStr("exim.importCancelled");
  415.       var sType = "info";
  416.       sm_notify("boxNotifyExim", sMessage, sType);
  417.     }
  418.     else {
  419.       var sMessage = sm_getLStr("exim.importFailed");
  420.       var sType = "critical";
  421.       sm_notify("boxNotifyExim", sMessage, sType);
  422.     }
  423.     $$("eximStatus").hidden = true;
  424.   },
  425.  
  426.   readCsvContent: function() {
  427.     var csvParams = {};
  428.  
  429.     var sTabName = $$("eximCsvTableName").value;
  430.     //returns true on OK, false on cancel
  431.     if (sTabName.length == 0) {
  432.       var sMessage = sm_getLStr("exim.import.invalidTablename");
  433.       var sType = "critical";
  434.       sm_notify("boxNotifyExim", sMessage, sType);
  435.       this.reportImportResult(-1);
  436.       return;
  437.     }
  438.     csvParams.tableName = sTabName;
  439.  
  440.     var cSeparator = $$("eximCsv_separator").value;
  441.     if(cSeparator == "other")
  442.       cSeparator = $$("eximCsv_separator-text").value;
  443.     else if(cSeparator == "\\t")
  444.       cSeparator = "\t";
  445.  
  446.     csvParams.separator = cSeparator;
  447.     csvParams.ignoreTrailingDelimiter = $$("eximCsv_ignoreTrailingDelimiter").checked;
  448.  
  449.     var cEncloser = $$("eximCsv_encloser").value;
  450.     if(cEncloser == "other")
  451.      cEncloser = $$("eximCsv_encloser-text").value;
  452.     else if (cEncloser == "din")
  453.       cEncloser = '"';
  454.  
  455.     csvParams.encloser = cEncloser;
  456.  
  457.     csvParams.bColNames = $$("eximCsv_column-names").checked;
  458.     csvParams.charset = $$("eximFileCharSet").value;
  459.  
  460. //////////////////////////
  461.  
  462.     var ios = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);
  463.     var URL = ios.newFileURI(this.mFileToImport);
  464.     // URL is a nsIURI; to get "file://...", use URL.spec
  465.     csvParams.file = URL.spec;
  466.  
  467.     this.importWorker = new Worker('workerCsv.js');  
  468.     this.importWorker.onmessage = function(event) {
  469.       var obj = event.data;
  470.  
  471.       if (typeof obj == 'string') {
  472.         SmExim.showImportStatus("Importing: " + event.data);
  473.         //sm_log("Importing: " + event.data);
  474.         return;  
  475.       }
  476.  
  477.       //if the worker failed, terminate it
  478.       if (obj.success == 0) {
  479.         alert(obj.description);
  480.         SmExim.handleImportCompletion(-1);
  481.         return;
  482.       }
  483.  
  484.       //if the worker succeeded, do things that should be done after the completed stage
  485.       switch (obj.stage) {
  486.         case 1: //file read; create table query is to be made
  487.           var sDbName = Database.logicalDbName;
  488.           var aRet = SmExim.getCreateTableQuery(obj.tableName, sDbName, obj.columns, false);
  489.           if (aRet.error) {
  490.             SmExim.handleImportCompletion(-1);
  491.             return;
  492.           }
  493.           var params = {stage: 2};
  494.           params.createTableQuery = aRet.query;
  495.           params.tableName = aRet.tableName;
  496.           SmExim.importWorker.postMessage(params);
  497.           break;
  498.  
  499.         case 2: //queries created; execution to be done
  500.           var answer = smPrompt.confirm(null, sm_getLStr("exim.confirm.rows.title"), sm_getLStr("exim.confirm.rows.msg") + obj.numRecords);
  501.           if(answer) {
  502.             if (obj.badLines.length > 0) {
  503.               var err = sm_getLFStr("exim.import.failed", [obj.badLines.length], 1) + obj.badLines.join(", ");
  504.               alert(err);
  505.             }
  506.             SmExim.showImportStatus("Importing: inserting " + obj.numRecords + " records in the database...");
  507.             //TODO: async might help
  508.             var bReturn = Database.executeTransaction(obj.queries);
  509.             //to use async, create query must be executed separately from insert queries (because, executeAsync expects array of statements, not strings; and createStatement fails if the table has not already been created.
  510.             // var bReturn = Database.executeAsync(obj.queries);
  511.             if (bReturn) {
  512.               SmExim.handleImportCompletion(obj.numRecords);
  513.               return;
  514.             }
  515.           }
  516.           SmExim.handleImportCompletion(-1);
  517.           return;
  518.           break;
  519.       }
  520.     };
  521.  
  522.     this.importWorker.onerror = function(error) {
  523.       alert(["CSV Worker error!", error.message, 'File name: ' + error.filename, 'Line number: ' + error.lineno].join('\n'));  
  524.       SmExim.handleImportCompletion(-1);
  525.     };
  526.  
  527.     csvParams.stage = 1;
  528.     this.importWorker.postMessage(csvParams);
  529.   },
  530.   
  531.   readSqlContent: function(file, charset) {
  532.     var sData = FileIO.read(file, charset);
  533.     var aQueries = sql_tokenizer(sData);
  534.     var bTransact = $$("eximSql-transact-statement").checked;
  535.     if (bTransact) {
  536.       //remove the first and last statement which should be
  537.       //BEGIN TRANSACTION and COMMIT respectively
  538.       aQueries.splice(0, 1);
  539.       aQueries.splice(aQueries.length - 1, 1);
  540.     }
  541.  
  542.     var answer = smPrompt.confirm(null, sm_getLStr("exim.confirm.sqlStats.title"), sm_getLStr("exim.confirm.sqlStats.msg") + aQueries.length);
  543.     if(answer) {
  544.       var bReturn = Database.executeTransaction(aQueries);
  545.       if (bReturn)
  546.         return aQueries.length;
  547.     }
  548.     return -1;
  549.   },
  550.   
  551.   readXmlContent: function(file, charset) {
  552.     var bType = $$("eximXml_type-attribute").checked;
  553.  
  554.     var aQueries = [];
  555.     //the following two arrays should be of equal length
  556.     var xmlTables = []; //unique table names in xml nodes
  557.     var actualTables = [];//names of tables as created
  558.  
  559.     var aCols = [];
  560.  
  561.     var sData = "";
  562.     //E4X doesn't support parsing XML declaration(<?xml version=...?>)(bug 336551)
  563.     //TODO:  yet to test
  564.     var sData = FileIO.read(file, charset);
  565.     sData = sData.replace(/<\?xml[^>]*\?>/, "");
  566.  
  567.     var xmlData = new XML(sData);
  568.     XML.ignoreComments = true;
  569.     var sDbName = xmlData.name().localName;
  570.     var iRows = xmlData.*.length();
  571.     var sCols, sVals, iCols, row, colText, sTabName, sQuery;
  572.     for (var i = 0; i < iRows; i++) {
  573.       row = xmlData.child(i);
  574.       sTabName = row.name().localName;
  575.       iCols = row.*.length();
  576.       sCols = "";
  577.       sVals = "";
  578.       aCols = [];
  579.       for (var j = 0; j < iCols; j++) {
  580.         colText = row.child(j).toString();
  581.         if (j != 0) {
  582.           sCols += ", ";
  583.           sVals += ", ";
  584.         }
  585.         sCols += SQLiteFn.quoteIdentifier(row.child(j).name().localName);
  586.         aCols.push(row.child(j).name().localName);
  587.         if (bType) {
  588.           if (row.child(j).@type == 3)
  589.             sVals += SQLiteFn.quote(colText);
  590.           else if (row.child(j).@type == 0)
  591.             sVals += "NULL";
  592.           else if (row.child(j).@type == 1)
  593.             sVals += colText;
  594.           else
  595.             sVals += SQLiteFn.quote(colText);
  596.         }
  597.         else
  598.           sVals += SQLiteFn.quote(colText);
  599.       }
  600.       var sDbName = Database.logicalDbName;
  601.       var sTabNameInInsert = Database.getPrefixedName(sTabName, sDbName);
  602.       var iFound = xmlTables.indexOf(sTabName);
  603.       if (iFound == -1) {
  604.         //last arg is true to indicate that user cannot edit column names needed until we can maintain arrays for original and new names like we do for tables using xmlTables & actualTables
  605.         var aRet = this.getCreateTableQuery(sTabName, sDbName, aCols, true);
  606.         if (aRet.error)
  607.           return -1;
  608.         if (aRet.query != "") {
  609.           aQueries.push(aRet.query);
  610.         }
  611.         xmlTables.push(sTabName);
  612.         actualTables.push(aRet.tableName);
  613.       }
  614.       iFound = xmlTables.indexOf(sTabName);
  615.       if (iFound >= 0) {
  616.         sTabNameInInsert = actualTables[iFound];
  617.       }
  618.       sQuery = "INSERT INTO " + sTabNameInInsert + " (" + sCols + ") VALUES (" + sVals + ")";
  619.       aQueries.push(sQuery);
  620.     }
  621.  
  622.     var answer = smPrompt.confirm(null, sm_getLStr("exim.confirm.irows.title"), sm_getLStr("exim.confirm.irows.msg") + iRows);
  623.     if(answer) {
  624.       var bReturn = Database.executeTransaction(aQueries);
  625.       if (bReturn)
  626.         return iRows;
  627.     }
  628.     return -1;
  629.   },
  630.  
  631.   getCreateTableQuery: function(sTabName, sDbName, aCols, bReadOnlyColNames) {
  632.     //importing to an existing table
  633.     if (Database.tableExists(sTabName, sDbName)) {
  634.       sTabName = Database.getPrefixedName(sTabName, sDbName);
  635.       //confirm before proceeding
  636.       //TODO: the buttons should say Continue (=OK), Abort (=Cancel)
  637.       // and Let me modify = open createTable.xul
  638.       var answer = smPrompt.confirm(null, sm_getLStr("exim.confirm.tabName.title"), sm_getLFStr("exim.confirm.tabName.msg", [sTabName], 1));
  639.       return {error: !answer, query: "", tableName: sTabName};
  640.     }
  641.  
  642.     //table needs to be created
  643.     var sQuery = "";
  644.     //ask whether the user wants to modify the new table
  645.     var answer = smPrompt.confirm(null, sm_getLStr("exim.confirm.createTable.title"), sm_getLFStr("exim.confirm.createTable.msg", [sTabName],1));
  646.     if(answer) { //if yes, call create table dialog
  647.       var aRetVals = {tableName: sTabName, colNames: aCols};
  648.       if (bReadOnlyColNames)
  649.         aRetVals.readonlyFlags = ["colnames"];
  650.       window.openDialog("chrome://sqlitemanager/content/createTable.xul",  "createTable", "chrome, resizable, centerscreen, modal, dialog", Database, aRetVals);
  651.       if (aRetVals.ok) {
  652.         sQuery = aRetVals.createQuery;
  653.         return {error: false, query: sQuery, tableName: aRetVals.tableName};
  654.       }
  655.     }
  656.     //user chose not to modify, or pressed cancel in create table dialog
  657.     sTabName = Database.getPrefixedName(sTabName, sDbName);
  658.     for (var ic = 0; ic < aCols.length; ic++)
  659.       aCols[ic] = SQLiteFn.quoteIdentifier(aCols[ic]);
  660.     var sCols = aCols.toString();
  661.     sQuery = "CREATE TABLE IF NOT EXISTS " + sTabName + " (" + sCols + ")";
  662.     return {error: false, query: sQuery, tableName: sTabName};
  663.   },
  664.  
  665.   saveCsvExportSetting: function() {
  666.    //separator
  667.     var cSeparator = $$("eximCsv_separator").value;
  668.     if(cSeparator == "other")
  669.       cSeparator = $$("eximCsv_separator-text").value;
  670.     else if(cSeparator == "\\t")
  671.       cSeparator = "\t";
  672.     //encloser
  673.     var cEncloser = $$("eximCsv_encloser").value;
  674.     if(cEncloser == "other")
  675.      cEncloser = $$("eximCsv_encloser-text").value;
  676.     //colnames needed or not
  677.     var bColNames = $$("eximCsv_column-names").checked;
  678.  
  679.  
  680.     var sPrefVal = sm_prefsBranch.getCharPref("jsonEximSettings");
  681.     var obj = JSON.parse(sPrefVal);
  682.  
  683.     obj.csv.export.separator = cSeparator;
  684.     obj.csv.export.encloser = cEncloser;
  685.     obj.csv.export.includeColNames = bColNames;
  686.  
  687.     sPrefVal = JSON.stringify(obj);
  688.     sm_prefsBranch.setCharPref("jsonEximSettings", sPrefVal);
  689.   }
  690. };
  691.